#include "ConversationWidget.h"
#include "RoQuery.h"

#include <QMetaObject>
#include <QMetaEnum>

#include "common.h"

#include "XmlGenerator.h"
typedef cblp::XmlGenerator XML;

ConversationWidget::ConversationWidget(QTabWidget *parent, int type, QString name) :
    super(parent),
    parentTabWidget(parent), // Т.к Qt меняет parent на QStackedWidget
    dialogQuery(0),
    _name(name) // Использется только для info-шек, чтобы отбирать необходимую info-шку.
{
    this->setupUi(this);

    errorTypeComboBox->setVisible (false);

    // Хочу чтобы был зелёненький.
    conversationTextEdit->setStyleSheet( " QTextEdit { color: green } ");

    switch (type)
    {
    case Conversation::Standard:
        {
            // Заполняем comboBox с типами ошибок.
            int index = RoIqStanza::staticMetaObject.indexOfEnumerator("ErrorType");

            for (int i = 0; i < RoIqStanza::staticMetaObject.enumerator(index).keyCount(); i++ )
            {
                errorTypeComboBox->addItem(RoIqStanza::staticMetaObject.enumerator(index).key(i),
                                           RoIqStanza::staticMetaObject.enumerator(index).value(i) );
            }

            // Сигналы и слоты
            connect(addButton, SIGNAL(clicked()),
                    this, SLOT(addInfo()) );
            connect(errorRadioButton, SIGNAL(toggled(bool)),
                    this, SLOT(handleErrorRadioButtonStateChange(bool)));
        }
        break;
    case Conversation::Info:
        {
            // Для отображения info-шек ничего и не нужно
            errorTypeComboBox->setVisible(false);
            datumRadioButton->setVisible(false);
            errorRadioButton->setVisible(false);
            resultRadioButton->setVisible(false);
            addButton->setVisible(false);
            addInfoLabel->setVisible(false);
            addInfoTextEdit->setVisible(false);
        }
        break;
    default:
        break;
    }
}

ConversationWidget::~ConversationWidget()
{
    ;//qDebug() << "ConversationWidget deleted";
}

void ConversationWidget::addLogText(QString text)
{
    conversationTextEdit->append(text);
}

void ConversationWidget::setButtonsState(bool state)
{
    // Проверим один из элементов. Остальные по идеи в этом же состоянии.
    if ( (datumRadioButton->isEnabled() && state == true) ||
         ( !datumRadioButton->isEnabled() && state == false ) )
        return;

    datumRadioButton->setEnabled(state);
    errorRadioButton->setEnabled(state);
    resultRadioButton->setEnabled(state);
    addButton->setEnabled(state);
}

void ConversationWidget::setLogText(QString text)
{
    conversationTextEdit->setText(text);
}

void ConversationWidget::addInfo()
{
    QString content = addInfoTextEdit->toPlainText();
    if (datumRadioButton->isChecked())
    {
        if(dialogQuery == 0)
            return;
        QDomDocument payLoad;
        payLoad.setContent(content);
        RoIqStanza::createDatum(dialogQuery->remoteComponentName(), dialogQuery->rid(), payLoad);

    }
    else if (resultRadioButton->isChecked())
    {
        if(dialogQuery == 0)
            return;
        QString claimant = dialogQuery->remoteComponentName();
        RoStanzaId rid = dialogQuery->rid();

        RoAbstractComponent* component = dialogQuery->parentComponent();

        component->sendStanza(RoIqStanza::createResult( claimant, rid, "ok" ));

    }
    else // errorRadioButton checked
    {
        if(dialogQuery == 0)
            return;

        QString claimant = dialogQuery->remoteComponentName();
        RoStanzaId rid = dialogQuery->rid();

        RoAbstractComponent* component = dialogQuery->parentComponent();

        QVariant data = errorTypeComboBox->itemData( errorTypeComboBox->currentIndex() );
        RoIqStanza::ErrorType* errorType = reinterpret_cast<RoIqStanza::ErrorType*>(&data);

        component->sendStanza(RoIqStanza::createError(*errorType, claimant, rid));
    }
}

void ConversationWidget::closeProperly()
{
    parentTabWidget->removeTab(parentTabWidget->indexOf(this));
    close();
    deleteLater();
}

void ConversationWidget::logInfoText(const RoInfoStanza & stanza)
{
    if (stanza.name() == _name) // Если имя info-шки совпало, то выводим.
    {
        addLogText(stanza.toString());
    }
}

void ConversationWidget::handleErrorRadioButtonStateChange(bool isChecked)
{
    if (isChecked)
    {
        errorTypeComboBox->setVisible(true);
    }
    else
    {
        errorTypeComboBox->setVisible(false);
    }
}

void ConversationWidget::receive_query_datum(QDomDocument datum)
{
    // Получаем диалог, в который хотим отправить данные.
    if ( dialogQuery == 0 )
        dialogQuery = qobject_cast<RoQuery*>(sender());

    addLogText(datum.toString());
}

void ConversationWidget::receive_query_result(bool error, QDomDocument answer)
{
    if(error)
    { qDebug() << "error occured"; }

    setButtonsState(false);
    addLogText(answer.toString());

}
